package com.thomasmoerman.dci2.tmc

import com.thomasmoerman.dci2.domain._
import com.thomasmoerman.dci2.frw._

trait MoneySource {
  
  class InsufficientFundsException extends RuntimeException
  
  def transferMoney(recipient: MoneySink, amount: Double)
  
}

trait MoneySourceProvider {
  
  def getMoneySource(accountId: Long): MoneySource
  
}

trait TransactionalMoneySourceProvider extends MoneySourceProvider {
  this: Transactional with UpdatableAccountAspect with CalculatedBalanceAspect =>
  
  def getMoneySource(accountId: Long) = new Account(accountId) with UpdatableAccount with CalculatedBalance with TransactionalMoneySource 
  
  trait TransactionalMoneySource extends MoneySource {
    self: Account with HasBalance =>

    def transferMoney(recipient: MoneySink, amount: Double) = {
      def checkBalance = if (amount > balance) throw new InsufficientFundsException
      
      inTransaction {
    	checkBalance

        self.decreaseBalance(amount)
        
        recipient.increaseBalance(amount)
      
        self.updateLog("balance decreased with $", amount)
      
        recipient.updateLog("balance increased with $", amount)
      }
    }
    
  }
  
}